﻿using JESAI.HttpRequestMonitor.Builders;
using JESAI.HttpRequestMonitor.Core;
using JESAI.HttpRequestMonitor.Core.Abstracts;
using JESAI.HttpRequestMonitor.Core.Builders;
using JESAI.HttpRequestMonitor.Core.Creator;
using JESAI.HttpRequestMonitor.Filters;
using JESAI.HttpRequestMonitor.Middlewares;
using JESAI.HttpRequestMonitor.Options;
using JESAI.HttpRequestMonitor.Process;
using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Options;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Microsoft.Extensions.DependencyInjection
{
    public static class ServiceCollectionExtensions
    {
        public static IHttpRequestMonitorBuilder AddHttpRequestMonitor(this IServiceCollection services)
        {
            IConfiguration configuration = services.BuildServiceProvider().GetService<IConfiguration>().GetSection("HttpRequestMonitor");
            services.AddOptions();
            services.Configure<HttpRequestMonitorOptions>(configuration);
            return services.AddHttpRequestMonitorService(configuration);
        }

        public static IHttpRequestMonitorBuilder AddHttpRequestMonitor(this IServiceCollection services, Action<HttpRequestMonitorOptions> options)
        {
            IConfiguration configuration = services.BuildServiceProvider().GetService<IConfiguration>().GetSection("HttpRequestMonitor");
            services.AddOptions();
            services.Configure<HttpRequestMonitorOptions>(options);

            return services.AddHttpRequestMonitorService(configuration);
        }

        private static IHttpRequestMonitorBuilder AddHttpRequestMonitorService(this IServiceCollection services, IConfiguration configuration)
        {
            services.AddSingleton<IModelCreator, DefaultModelCreator>();
            services.AddSingleton<IHttpInvokeProcesser, DefaultHttpInvokeProcesser>();
            services.AddSingleton<IRequestMonitorTransport, DirectlyReportsTransport>();
            services.AddSingleton<IRequestModelBuilder, DefaultRequestModelBuilder>();

            services.AddMvcCore(x =>
            {
                x.Filters.Add<HttpRequestMonitorExceptionFilter>();
            });

            return new HttpRequestMonitorBuilder(services, configuration);
        }

        public static IHttpRequestMonitorInitializer UseHttpRequestMonitor(this IApplicationBuilder app)
        {
            Activity.DefaultIdFormat = ActivityIdFormat.W3C;

            var options = app.ApplicationServices.GetRequiredService<IOptions<HttpRequestMonitorOptions>>();

            if (!options.Value.Enable)
                return null;

            app.UseMiddleware<DefaultRequestMonitorMiddleware>();

            return app.InitHttpRequestMonitor().InitStorage();
        }
    }
}
